﻿package bdz.extensions.youtube.ui {
	
	import bdz.common.display.DisplayLoader;
	import bdz.common.events.GenericEvent;
	import bdz.controls.VideoController;
	import bdz.extensions.youtube.events.YTPlayerEvent;
	import flash.display.*;
	import flash.events.*;
	import flash.geom.Point;
	import flash.net.LocalConnection;
	import flash.utils.*;
	
	/**
	 * ...
	 * @author Donald
	 */
	public class YTChromelessPlayer extends MovieClip {
		private var _loader:DisplayLoader;
		private var _content:*;
		private var _duration:Number;
		private var _progTimer:Timer;
		private var _defWidth:Number = 615;
		private var _defHeight:Number = 360;
		private var _currentStatus:Number;
		private var _started:Boolean = false;
		private var _autohideVolume:Boolean = false;
		private var _hideWatermark:Boolean = true;
		private var _timeOutCheck:Timer;
		private var _alternativePlayer:Boolean = false;
		private var _altLoader:DisplayLoader;
		private var _altHolder:MovieClip;
		private var lc:LocalConnection;
		function YTChromelessPlayer(w:Number = 615, h:Number = 360) {
			_defWidth = w;
			_defHeight = h;
			addEventListener(Event.ADDED_TO_STAGE, initializeComponent);
		}
		private function initializeComponent(evt:Event):void {
			_progTimer = new Timer(100, 0);
			_progTimer.addEventListener(TimerEvent.TIMER, onPlayerProgress);
			_loader = new DisplayLoader();
			_loader.addEventListener(Event.COMPLETE, onPlayerLoaded);
			_loader.source = "http://www.youtube.com/apiplayer?version=3";

			_timeOutCheck = new Timer(60000, 1);
			_timeOutCheck.addEventListener(TimerEvent.TIMER, onTimeoutCheck);
			_timeOutCheck.start();
		}
		private function onTimeoutCheck(evt:TimerEvent):void {
			return;
			_alternativePlayer = true;
			
			try{
				_loader.unload();
				_loader = null;
				removeChild(_loader);
			}catch(e:Error){}
			_timeOutCheck.stop();
			trace("using alt player?");
			lc = new LocalConnection()
			lc.addEventListener(StatusEvent.STATUS, onStatus);
			lc.client = this;
			_altLoader = new DisplayLoader();
			_altLoader.source = "AVM1Loader.swf";
			_altLoader.addEventListener(Event.COMPLETE, alternativeLoaded);
			addChild(_altLoader);
		}
		private function alternativeLoaded(evt:Event):void {
			var ye:YTPlayerEvent = new YTPlayerEvent(YTPlayerEvent.READY);
			ye.alternativePlayer = _alternativePlayer;
			dispatchEvent(ye);
		}
		private function handleAlternativeLoad(vid:String):void {
			lc.send("avm_receiver", "loadVideo", vid)
		}
		private function onStatus(evt:StatusEvent):void {
			
		}
		private function onPlayerLoaded(evt:Event):void {
			if(!_alternativePlayer){
				try{
					_content = _loader.content;
					_content.addEventListener("onReady", onPlayerReady);
					_content.addEventListener("onError", onPlayerError);
					_content.addEventListener("onStateChange", onPlayerStateChange);
					_content.addEventListener("onPlaybackQualityChange", onVideoPlaybackQualityChange);
					addChild(_loader);
				}catch(e:Error){}
				
			}
		}
		private function onPlayerReady(evt:Event):void {
			_timeOutCheck.stop();
			dispatchEvent(new YTPlayerEvent(YTPlayerEvent.READY));
			_content.setSize(_defWidth, _defHeight);
			_content.visible = true;
			if(_hideWatermark){
				try {
					//_content.getChildAt(0).content.removeChild(_content.getChildAt(0).content.getChildAt(3));
				}catch (e:Error) { trace(e.message) }
			}
		}
		private function onPlayerProgress(evt:TimerEvent):void {
			
			
			var evtype:String = "";
			switch(_currentStatus) {
				case -1:
				//unstarted
					evtype = YTPlayerEvent.IDLE;
				break;
				case 0:
				//ended
					evtype = YTPlayerEvent.COMPLETED;
				break;
				case 1:
				//playing
					
					if(_started){
						evtype = YTPlayerEvent.PLAYING;
					}else {
						_content.setVolume(100);
						_started = true;
						evtype = YTPlayerEvent.STARTED;
					}
				break;
				case 2:
				//paused
					evtype = YTPlayerEvent.PAUSED;
				break;
				case 3:
				//buffering
					evtype = YTPlayerEvent.BUFFERING;
				break;
				case 5:
				//cued
					evtype = YTPlayerEvent.QUEUED;
				break;
			}
			
			var pevent:YTPlayerEvent = new YTPlayerEvent(evtype);
			pevent.bytesLoaded = _content.getVideoBytesLoaded();
			pevent.bytesTotal = _content.getVideoBytesTotal();
			pevent.startBytes = _content.getVideoStartBytes();
			pevent.duration = _content.getDuration();
			pevent.elapsedTime = _content.getCurrentTime();
			pevent.totalLoad = pevent.bytesLoaded / pevent.bytesTotal;
			pevent.percentPlayed = pevent.elapsedTime / pevent.duration;
			
			var pevent2:YTPlayerEvent = pevent.cloneNewType(YTPlayerEvent.PROGRESS);
			dispatchEvent(pevent2);
			dispatchEvent(pevent);
		}
		private function onPlayerError(evt:Event):void {
			
		}
		private function onPlayerStateChange(evt:Event):void {
			_duration = _content.getDuration();
			_currentStatus = Object(evt).data;
			_content.setSize(_defWidth, _defHeight);
			_content.visible = true;
		}
		private function onVideoPlaybackQualityChange(evt:Event):void {
			
			
			_content.setSize(_defWidth, _defHeight);
			
			
			
			
			_content.visible = true;
		}
		public function loadVideo(vid:String, seek:Number = 0, quality:String = "hd720"):void {
			if (_alternativePlayer) {
				handleAlternativeLoad(vid);
				return;
			}
			_progTimer.stop();
			if(_started){
				_content.cueVideoById(vid, seek, quality);
				_content.setSize(_defWidth, _defHeight);
				_content.visible = false;
				_content.playVideo();
				
			}else {
				_content.loadVideoById(vid, seek, quality);
			}
			_progTimer.start();
			dispatchEvent(new YTPlayerEvent(YTPlayerEvent.LOADING));
			_started = false;
		}
		public function playVideo():void {
			_content.playVideo();
		}
		public function pauseVideo():void {
			_content.pauseVideo();
		}
		public function stopVideo():void {
			_content.stopVideo();
		}
		public function seek(n:Number, seekahead:Boolean = true):void {
			_content.seekTo(n, seekahead);
		}
		public function set volume(n:Number):void {
			_content.setVolume(n*100);
		}
		public function get volume():Number {
			return _content.getVolume()/100;
		}
		public function set hideWatermark(b:Boolean):void {
			_hideWatermark = b;
		}
		public function get hideWatermark():Boolean {
			return _hideWatermark;
		}
	}
	
}